home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Die Speccy' 97
/
Die Speccy' 97.iso
/
amiga_system
/
the_aminet
/
comm
/
bbs
/
maxshell101.lha
/
MAXShell.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-09-14
|
26KB
|
996 lines
/*
MAXShell v1.01 - A door for running CLI based programs under M A X's BBS
~~~~~~~~~~~~~~
Based on TrShell, by Timothy Aston. Max's adaption by MPS '95!
See MAXShell.DOC for information on using this program.
*/
const char version[]="\0$VER: MAXShell 1.01 ("__DATE__")\0";
#include <clib/exec_protos.h>
#include <exec/exec.h>
#include <exec/types.h>
#include <exec/memory.h>
#include <exec/ports.h>
#include <exec/libraries.h>
#include <fcntl.h>
#include <libraries/dos.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "fifo.h"
#include "fifopr.h"
#include <proto/exec.h>
#include <proto/dos.h>
#include <time.h>
#define ESC 27
#define FF 12
char StrOut[255]; /* Output String! */
struct Library *FifoBase=NULL;
struct MsgPort *fifoport;
void *fifoR=NULL, *fifoW=NULL;
struct Message rmsg,wmsg;
char fifoname[30]="12345678901234567890123456789"; /* Name of FIFO */
char commandline[80]="NewShell FIFO:";
/* Command line for opening a FIFO: redirected CLI */
char newfile[30]="";
/* Filename for autoinsert-converted shell-startup */
char newchar=' '; /* Character used to replace spaces in user name */
char charbuf[100],txt[255];
char *fifoslav,*fifomast;
BOOL quit=FALSE;
BOOL readpending=FALSE, writepending=FALSE;
LONG n;
BOOL filterc=FALSE, filterd=FALSE, filtere=FALSE, filterf=FALSE, lesstime=FALSE;
void setup_fifo(void);
void shell_loop(void);
void Out(char *);
int InChar(void);
void SendBreak(char);
void check_fifo(void);
void OutLen(char * , ULONG);
void convert_lf(char * , char * , LONG);
void show_usage(void);
void close_all(void);
long getuserint(int);
void checkkey(char *);
void GetAutoInsert(char, char *);
void end(void);
void getsvar(int, char *);
void sendmessage(char[], int);
void hotkey(char[], char *);
void prompt(char[], char *, int);
void showfile(char[]);
void domenu(int, int, char *);
void changeuserint(int, long);
struct DoorMsg {
struct Message Door_Msg;
short command;
short data;
char string[80];
short carrier;
};
struct DoorMsg *doormsg, *garbage;
struct MsgPort *MyPort, *replyport;
struct Task *mytask; /* Pointer to this task so we can name it */
int err;
char linebuf[3000]=""; /* Line buffer */
time_t timeval; /* So we can get the time (For a different FIFO name */
time_t *timeptr; /* every time the door is run (Avoiding the closing bug) */
FILE *ifp, *ofp, *fopen();
/* FILE *ofp2; */
/*
* end() - Notifies Paragon that we are done and ready to continue with
* the BBS. ALWAYS use this to exit from your program, or
* the BBS will go to never-never land.
*/
void end(void)
{
doormsg->command = 20;
PutMsg(MyPort,(struct Message *)doormsg);
(void)WaitPort(replyport);
(void)GetMsg(replyport);
FreeMem(doormsg,(long)sizeof(*doormsg));
DeletePort(replyport);
exit(0);
}
/*
* getsvar(typ,mstring) - Gets certain string variables from Paragon.
* "mstring" is a pointer to a string to dump the string into. "typ" tells
* it what you want: 1=Name, 2=Password, 3=Address, 4=City, 5=State
* 6=Postal code, 7=Door pathname, 8=Default BBS pathname.
*/
/* Extra Max's values: 9: Date
10: Time
100: Phone number
101: Computer type
102: Comment (as defined by Sysop) */
void getsvar(typ,mstring)
int typ;
char *mstring;
{
doormsg->data = typ;
doormsg->command = 14;
PutMsg(MyPort,(struct Message *)doormsg);
(void)WaitPort(replyport);
strcpy(mstring,doormsg->string);
(void)GetMsg(replyport);
}
/*
* sendmessage(mstring,nl) - Sends a message to the local window and to
* the modem (if applicable). "mstring" is the output string you want to
* send, "nl" is an integer which is 1 if you want it to send the
* c/r+l/f combination, or 0 if not.
*/
void
sendmessage(mstring,nl)
char mstring[];
int nl;
{
char newstr[100];
int i, ii=0;
if (doormsg->carrier==1) return; /* Make sure no output is attempted if
carrier lost */
doormsg->data = nl;
doormsg->command = 1;
/* Strip out some escape codes unsupported by Max's. What do they do anyway?
This INCREDIBLY sloppy code just makes things like Contris and Vampire's
Castle look better rather than having strange [ p's, etc. showing up) */
for(i=0; i<strlen(mstring); i++)
{
newstr[ii]=mstring[i];
if(newstr[ii]=='\033' && mstring[i+1]=='[' && mstring[i+3]==' '
&& mstring[i+4]=='p')
{
ii--;
i+=4;
}
else if(newstr[ii]=='\033' && mstring[i+1]=='[' && mstring[i+2]==' '
&& mstring[i+3]=='p')
{
ii--;
i+=3;
}
else if(newstr[ii]=='\033' && mstring[i+1]=='\033' && mstring[i+2]=='['
&& mstring[i+3]==' ' && mstring[i+4]=='p')
{
ii--;
i+=4;
}
else if(newstr[ii]=='\033' && mstring[i+1]=='\033' && mstring[i+2]=='['
&& mstring[i+4]==' ' && mstring[i+5]=='p')
{
ii--;
i+=5;
}
else if(newstr[ii]=='\233' && mstring[i+1]==' ' && mstring[i+2]=='p')
{
ii--;
i+=3;
}
else if(newstr[ii]=='\233' && mstring[i+1]=='0' && mstring[i+2]==' '
&& mstring[i+3]=='p')
{
ii--;
i+=4;
}
/* else if(newstr[ii]=='\033' && mstring[i+1]=='[' && mstring[i+5]=='f')
{
ii--;
i+=6;
}
else if(newstr[ii]=='\033' && mstring[i+1]=='[' && mstring[i+6]=='f')
{
ii--;
i+=7;
}
else if(newstr[ii]=='\033' && mstring[i+1]=='[' && mstring[i+7]=='f')
{
ii--;
i+=8;
} */
ii++;
}
newstr[ii]='\0';
strcpy(doormsg->string,"");
PutMsg(MyPort,(struct Message *)doormsg);
(void)WaitPort(replyport);
(void)GetMsg(replyport);
if(newstr[0]!='\0')
{
strcpy(doormsg->string,newstr);
PutMsg(MyPort,(struct Message *)doormsg);
(void)WaitPort(replyport);
(void)GetMsg(replyport);
}
strcpy(doormsg->string,"");
PutMsg(MyPort,(struct Message *)doormsg);
(void)WaitPort(replyport);
(void)GetMsg(replyport);
/* fprintf(ofp2, "<-%s", newstr); */
}
/*
* hotkey(mstring,ostring) - outputs the string "mstring" and waits
* for one key which it will place in element [0] of "ostring".
* "mstring" may be a null string, in which case it will only wait for
* the key, and not output any prompt.
*/
void
hotkey(mstring,ostring)
char mstring[];
char *ostring;
{
strcpy(doormsg->string,mstring);
doormsg->command = 8;
PutMsg(MyPort,(struct Message *)doormsg);
(void)WaitPort(replyport);
(void)GetMsg(replyport);
strcpy(ostring,doormsg->string);
}
/*
* prompt(mstring,ostring,len) - outputs the string "mstring" and inputs
* a string which is placed in ostring. 'len' is the maximum number of
* characters which will be accepted.
*/
void
prompt(mstring,ostring,len)
char mstring[];
char *ostring;
int len;
{
strcpy(doormsg->string,mstring);
doormsg->data=len;
doormsg->command = 6;
PutMsg(MyPort,(struct Message *)doormsg);
(void)WaitPort(replyport);
(void)GetMsg(replyport);
strcpy(ostring,doormsg->string);
}
/* showfile(mstring) shows the text file which mstring is the path to.
It handles ^C aborting, and ^S/^Q pausing. */
void
showfile(mstring)
char mstring[];
{
strcpy(doormsg->string,mstring);
doormsg->command = 10;
PutMsg(MyPort,(struct Message *)doormsg);
(void)WaitPort(replyport);
(void)GetMsg(replyport);
}
/****************************************************
These two functions were added by
SWhite. MAX's BBS only!
****************************************************/
/* enter a menu function to execute 1-33 */
void
domenu(menu,extra,filename)
int menu,extra;
char *filename;
{
strcpy(doormsg->string,filename);
doormsg->command = menu+100;
doormsg->data = extra;
PutMsg(MyPort,(struct Message *)doormsg);
(void)WaitPort(replyport);
(void)GetMsg(replyport);
}
/* Change user information 1-15:
0 NextEventMinutes
1 UserTimeRemaining
2 AccessLevel
3 TimeLeft
4 DL Ratio
5 Last Message Read
6 PageLength
7 NumCalls
8 UserMessages #
9 UserUpped Files
10 UserDownedFiles
11 LastDayOn
12 Last Minute On
13 UserConfig Flags ;Lower 2 Bytes
Flags, bits: 0-Rd, 1-Wr, 2-Up, 3-Dn, 4-Bltn, 5-ANSI
6-FSE, 7-Pause, 8-Cls, 9-Lck, 10-Get file
description, 11-Junk mail, 12-Allow File
Attaches
14 UserTimeBank
15 XFer Protocol
16 MaxTimeBank
*/
void
changeuserint(number,val)
int number;
long val;
{
long *ptr;
ptr = (long *)&doormsg->string; /* We need a long value not a ptr */
*ptr = val;
doormsg->command = 200;
doormsg->data = number;
PutMsg(MyPort,(struct Message *)doormsg);
(void)WaitPort(replyport);
(void)GetMsg(replyport);
}
/* Get a piece of the user's integer information:
1: Access Level
2: Expert mode? (Paragon)
3: Net Credits? (paragon)
4: Number of calls
5: Calls to system
6: Graphics mode
7: Minutes remaining
8: Screen columns
9: Screen rows
100: Daily time limit
101: File ratio
102: Last message read (Updated when user logs off)
103: Messages posted
104: Files uploaded
105: Files downloaded
106: ?
107: ?
108: Flags (Binary bits)
+--------+------------+--------+---------------+
| FLAG | VALUE | FLAG | VALUE | Examples
+--------+------------+--------+---------------+ ~~~~~~~~
| Read | 1 (2^0) | Pause | 128 (2^7) | ALL ON : 8191
| Write | 2 (2^1) | CLS | 256 (2^8) | ALL OFF : 0
| Upld | 4 (2^2) | Lock | 512 (2^9) | Upld + Dnld : 12
| Dnld | 8 (2^3) | GFD | 1024 (2^10) | ANSI + FSE : 96
| Bltn | 16 (2^4) | Junk | 2048 (2^11) |
| ANSI | 32 (2^5) | AFA | 4096 (2^13) |
| FSE | 64 (2^6) | | |
+--------+------------+--------+---------------+
109: Amount in time bank
110: Protocol
111: Max time bank
*/
long getuserint(int val)
{
doormsg->command=13;
doormsg->data=val;
PutMsg(MyPort,(struct Message *)doormsg);
(void)WaitPort(replyport);
(void)GetMsg(replyport);
return(doormsg->data);
}
/* Check for a key, without any waiting or prompting */
void CheckKey(char *ostring)
{
doormsg->command = 201;
PutMsg(MyPort,(struct Message *)doormsg);
(void)WaitPort(replyport);
(void)GetMsg(replyport);
strcpy(ostring,doormsg->string);
}
/* Return Max's auto insert (And also replace spaces with defined
substitution character, in the full user name, if applicable) */
void GetAutoInsert(char istring, char *ostring)
{
int i;
doormsg->command = 203;
doormsg->data = istring;
PutMsg(MyPort,(struct Message *)doormsg);
(void)WaitPort(replyport);
(void)GetMsg(replyport);
strcpy(ostring,doormsg->string);
if(istring=='f')
{
for(i=0;i<strlen(ostring);i++)
{
if(ostring[i]==' ')
{
ostring[i]=newchar;
}
}
}
if(istring=='k' && lesstime==TRUE)
{
i=atoi(ostring);
i-=5;
if(i<0) i=0;
sprintf(ostring, "%d", i);
}
}
/* Setup FIFO, requires Dillon's fifo.library.
*/
void setup_fifo()
{
fifoslav = (char *) malloc(strlen(fifoname) + 16);
fifomast = (char *) malloc(strlen(fifoname) + 16);
sprintf(fifomast, "%s_m", fifoname);
sprintf(fifoslav, "%s_s", fifoname);
fifoport=CreatePort(NULL,0L);
fifoW = OpenFifo(fifomast, 2048, FIFOF_WRITE|FIFOF_NORMAL|FIFOF_NBIO);
if (fifoW == NULL)
{
printf("ERROR: Unable to open fifo %s\n", fifomast);
/* Temporary: I'll have to change this... */
exit(10);
}
fifoR = OpenFifo(fifoslav, 2048, FIFOF_READ|FIFOF_NORMAL|FIFOF_NBIO);
if (fifoR == NULL)
{
printf("ERROR: Unable to open fifo %s\n", fifoslav);
/* Temporary: I'll have to change this... */
exit(10);
}
rmsg.mn_ReplyPort = fifoport;
wmsg.mn_ReplyPort = fifoport;
}
/* The main shell loop.
*/
void shell_loop(void)
{
char c;
char outstr[100];
sprintf(outstr, "\r\nMAXShell v1.01\n\r\n");
Out(outstr);
RequestFifo(fifoR,&rmsg,FREQ_RPEND);
readpending=TRUE;
while (quit==FALSE)
{
c=InChar();
switch ( (int) c)
{
case 3:
if(filterc==FALSE) SendBreak('C');
break;
case 4:
if(filterd==FALSE) SendBreak('D');
break;
case 5:
if(filtere==FALSE) SendBreak('E');
break;
case 6:
if(filterf==FALSE) SendBreak('F');
break;
default:
n=WriteFifo(fifoW,&c,1);
if (n<1)
{
if (writepending==FALSE)
{
RequestFifo(fifoW,&wmsg,FREQ_RPEND);
writepending=TRUE;
}
}
break;
}
};
sendmessage(charbuf, 0); /* Flush the character buffer */
n=WriteFifo(fifoW,"\r",1);
if (n<1)
{
if (writepending==FALSE)
{
RequestFifo(fifoW,&wmsg,FREQ_RPEND);
writepending=TRUE;
}
}
}
/* Get a character, complete with carrier checks and rudimentry idle timer
* checking. Serial routines are smart enough to know whether or not
* serial I/O should place or not, so there's no need to check if this is
* a local logon or anything like that.
*/
int InChar()
{
ULONG l;
for (;;)
{
CheckKey(StrOut);
l=StrOut[0];
if (l)
return(StrOut[0]);
if (doormsg->carrier==1)
{
sprintf(txt,"%c[0;31m%cCarrier Lost.%c[37m\r\n",ESC,FF,ESC);
Out(txt);
SendBreak('C');
quit=TRUE;
return(0);
}
/* See if anything has come from out FIFO
*/
check_fifo();
if (quit==TRUE)
return(0);
/* Fix this crap later... (Don't think it's needed for Max's anyway!) */
/*
WaitTOF();
t++;
if (t>100000)
{
sprintf(txt,"%c[0;31m%cInactivity timeout.%c[37m\r\n",ESC,FF,ESC); Out(txt);
quit=TRUE;
SendBreak('C');
return(0);
}
*/
}
}
/* Check for something from FIFO.
*/
void check_fifo()
{
struct Message *msg;
char *ptr;
msg=GetMsg(fifoport);
if (msg==(struct Message *)&rmsg)
{
readpending=FALSE;
n=ReadFifo(fifoR,&ptr,0);
if (n>0)
{
/* These 2 values were 256, but changed them to this lower value to stop
the program crashing (DoorMsg struct has room for only 80 characters) */
if (n>40)
n=40;
OutLen(ptr,n);
n=ReadFifo(fifoR,&ptr,n);
}
if (n<0)
quit=TRUE;
else
{
RequestFifo(fifoR,&rmsg,FREQ_RPEND);
readpending=TRUE;
}
}
else if (msg==(struct Message *)&wmsg)
writepending=FALSE;
}
/* Text output to the serial device and the terminal window. The serial
* routines are smart enough to know whether serial I/O should take place
* or not, so its perfectly safe to always call them like this.
*/
void Out(char *str)
{
char temp[3000];
convert_lf(temp,str,strlen(str));
sendmessage(temp, 0);
}
void OutLen(char *str, ULONG len)
{
int counter, counter2, newlen, escape;
char temp[3000];
convert_lf(temp,str,len);
/* Check for a partial escape sequence at the end of the string, and save
it for the start of the next string, if required */
newlen=strlen(temp);
counter=newlen;
escape=FALSE;
while(counter>newlen-12 && counter>=0 && escape==FALSE)
{
if(temp[counter]=='\033')
{
escape=TRUE;
}
counter--;
}
counter2=counter;
counter2++;
while(counter2<newlen && escape==TRUE)
{
counter2++;
if((temp[counter2]>='A' && temp[counter2]<='Z')
|| (temp[counter2]>='a' && temp[counter2]<='z'))
{
escape=FALSE;
}
}
if(escape==TRUE)
{
strncat(charbuf, temp, counter);
sendmessage(charbuf, 0);
strmid(temp, charbuf, counter+1, newlen-counter+1);
}
else
{
strcat(charbuf, temp);
/* Make sure the resultant string (Old character buffer with partial escape
sequence, and new string which doesn't have the start of a partial escape
sequence) isn't still a partial escape sequence, before printing it. If
the string is a partial escape sequence, leave it stored in the character
buffer for next time around */
counter=0;
newlen=strlen(charbuf);
while(counter<newlen)
{
if(charbuf[counter]=='\033')
{
escape=TRUE;
while(counter<newlen)
{
counter++;
if((charbuf[counter]>='a' && charbuf[counter]<='z')
|| (charbuf[counter]>='A' && charbuf[counter]<='Z'))
{
escape=FALSE;
break;
}
}
}
counter++;
}
if(escape==FALSE)
{
sendmessage(charbuf, 0);
strcpy(charbuf, "");
}
}
}
/* Strip CR's from string, plus a few other conversions!
*/
void convert_lf(char *buf, char *str, LONG len)
{
LONG i, ii=0;
for (i=0; i<len; i++)
{
buf[ii]=str[i];
/* Stop Max's from converting special display sequences */
if(buf[ii]=='|')
{
buf[ii+1]='\013';
ii++;
}
if(buf[ii]=='@')
{
buf[ii+1]='\013';
ii++;
}
if(buf[ii]=='%')
{
buf[ii+1]='\013';
ii++;
}
/* Add in an extra escape for each escape character found */
if(buf[ii]=='\033')
{
buf[ii+1]='\033';
ii++;
}
/* Take out CR's */
if (buf[ii]=='\r')
{
ii--;
}
ii++;
}
buf[ii]='\0';
}
/* Display command line usage */
void show_usage(void)
{
printf("-- MAXShell v1.01 by MPS in 1995!\n");
printf("-- Based on the original TrShell by Tim Aston\n");
printf("-- M A X's BBS Remote Shell\n\n");
printf("Usage:\n\nMAXShell <startup-script> [-c] [-d] [-e] [-f] [-s<substitution char>] [-t]\n\n");
}
/* Send a break.
*/
void SendBreak(char c)
{
char buf[256];
LONG fh;
sprintf(buf, "FIFO:%s/%c", fifoname, c);
if (fh = Open(buf, 1005))
Close(fh);
}
/* Cleanly and safely shutdown all resources.
*/
void WaitMsg(struct Message *msg)
{
while (msg->mn_Node.ln_Type == NT_MESSAGE)
Wait(1 << msg->mn_ReplyPort->mp_SigBit);
Forbid();
Remove(&msg->mn_Node);
Permit();
}
main(int argc, char *argv[])
{
/* char userstring[1000]; */
char linein[256], lineout[256], linestring[80];
long uservalue, savedflags;
int i, ii, j;
char buffer[81],line_number;
char cportname[12]; /* ReplyPort and Control Port names */
char infilename[80]="DOORS:MAXSHELL/";
/* Pull out the line number from the argv field to find where we are */
line_number=argv[argc-1][0];
mytask=(struct Task *)FindTask('\0');
mytask->tc_Node.ln_Name = "DoorExample";
/* Create the Reply port, with the name based on the number... */
sprintf(buffer,"DoorReply%c",line_number);
replyport=(struct MsgPort *)CreatePort(buffer,0L);
doormsg=(struct DoorMsg *)AllocMem((long)sizeof(*doormsg),MEMF_PUBLIC);
if(doormsg==0)
{
puts("Couldn't allocate DoorMsg!");
show_usage();
return;
}
doormsg->Door_Msg.mn_Node.ln_Type = NT_MESSAGE;
doormsg->Door_Msg.mn_ReplyPort = replyport;
doormsg->Door_Msg.mn_Length = (UWORD)sizeof(*doormsg);
/* Locate the correct DoorControl port based on the line number */
sprintf(cportname,"DoorControl%c",line_number);
MyPort=(struct MsgPort *)FindPort(cportname);
if(MyPort==0L)
{
puts("DoorControl port not located!");
FreeMem(doormsg,(long)sizeof(*doormsg));
show_usage();
return;
}
/* Parse command line switch arguments.
*/
for (i=1; i<argc; i++)
{
if (argv[i][0]=='-')
{
switch (argv[i][1])
{
case 'c':
case 'C':
filterc=TRUE;
break;
case 'F':
case 'f':
filterf=TRUE;
break;
case 'D':
case 'd':
filterd=TRUE;
break;
case 'E':
case 'e':
filtere=TRUE;
break;
case 's':
case 'S':
newchar=argv[i][2];
break;
case 'T':
case 't':
lesstime=TRUE;
}
}
}
/* Open a CLI redirected to FIFO: based on an individual filename
generated from the system time (Hope it's not too long!) */
/* The same filename is also used for the names of the two FIFO's, opened
later */
timeval=time(timeptr);
sprintf(fifoname, "%d_%c", timeval, line_number);
strcat(commandline, fifoname);
strcat(commandline, "/rwkecs");
if(argc>2)
{
/* Generate a new Shell-Startup script with proper autoinserts
(Name is based on the same FIFO: filename used above) */
strcat(infilename, argv[1]);
ifp=fopen(infilename, "r");
if(ifp==NULL)
{
sendmessage("Can't open given startup script - Opening a standard shell.\r\n", 0);
}
else
{
sprintf(newfile,"RAM:%s", fifoname);
ofp=fopen(newfile, "w");
while(fgets(linein, 256, ifp)!=NULL)
{
ii=0;
for(i=0; i<strlen(linein);i++)
{
lineout[ii]=linein[i];
if(lineout[ii]=='%')
{
i++;
GetAutoInsert(linein[i], linestring);
for(j=0; j<strlen(linestring); j++)
{
lineout[ii]=linestring[j];
ii++;
}
ii--;
}
ii++;
}
lineout[ii]='\0';
fprintf(ofp, "%s", lineout);
}
fclose(ifp);
fclose(ofp);
/* ... and add the right stuff to the command line. */
strcat(commandline," FROM ");
strcat(commandline, newfile); /* Converted Shell-Startup script */
}
}
system(commandline);
/*
sendmessage(commandline,1);
sendmessage("\r\nHi there! Welcome to the test version of MAXShell\r\n",1);
uservalue=getuserint(1);
sprintf(userstring, "The user's flags value: %ld\n", uservalue);
sendmessage(userstring, 0);
hotkey("Press any key to (most likely) crash the computer...",buffer);
*/
/* ofp2=fopen("ram:test", "w"); */
/* Set user's PAUSE flag to OFF, so the annoying 'Press Return' doesn't appear
all the time in scrolling text doors such as Hack & Slash (And the standard
shell). The user's previous flag value is saved for restoration before
returning back to the BBS */
uservalue=getuserint(108);
savedflags=uservalue;
uservalue&=0xffffff7fL; /* Turn bit 7 (Pause) of the user's flags OFF */
changeuserint(13, uservalue);
/* Open fifo.library.
*/
FifoBase=OpenLibrary("fifo.library",0L);
if(!FifoBase)
{
printf("ERROR: Couldn't open fifo.library\n");
/* Temporary: I'll have to change this ... */
exit(10);
CloseLibrary(FifoBase);
}
setup_fifo();
shell_loop();
close_all();
/* Delete temporary shell-startup file... */
strcpy(linein, "c:delete ");
strcat(linein, newfile);
system(linein);
/* Restore user's previous PAUSE flag setting */
changeuserint(13, savedflags);
/* Close down the door... */
/* fclose(ofp2); */
end();
}
void close_all(void)
{
if (readpending)
{
RequestFifo(fifoR, &rmsg, FREQ_ABORT);
WaitMsg(&rmsg);
}
if (writepending)
{
RequestFifo(fifoW, &wmsg, FREQ_ABORT);
WaitMsg(&wmsg);
}
if (fifoR) CloseFifo(fifoR, FIFOF_EOF);
if (fifoW) CloseFifo(fifoW, FIFOF_EOF);
if (fifoport) DeletePort(fifoport);
if (FifoBase) CloseLibrary(FifoBase);
}